package base
{
    import com.dusk.game.Logger;
    import com.dusk.util.McUtil;
    import com.dusk.util.UtilBase;
    import com.game.manager.AnimationManager;
    import com.game.view.IAnimation;
    
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.utils.Dictionary;
    
    public class BaseAnimation extends Sprite
    {
        
        public function BaseAnimation(dict:Dictionary = null)
        {
            super();
            if(dict) _clipDict = dict;
            else _clipDict = new Dictionary();
        }
        
        public var sourceName:String;
        public var replace:Object;
        public var animationType:int;
        
        private var _isPlaying:Boolean = true;
        private var _curClip:IAnimation;
        private var _clipDict:Dictionary;
        private var _curAction:String;
        private var _offsetX:int;//偏移量X
        private var _offsetY:int;//偏移量Y
        
        protected var enterFrameFunc:Function;//进入帧回调
        protected var actionOverFunc:Function;//动作循环结束回调
        
        /**
         * 添加总回调
         * @param enterFrame 进入帧回调
         * @param actionOver 动作结束回调
         */
        public function addCallBack(enterFrame:Function = null, actionOver:Function = null):void
        {
            enterFrameFunc = enterFrame;
            actionOverFunc = actionOver;
        }
        
        /**
         * 设置进入帧回调
         * @param func 回调函数
         */
        public function setEnterFrameCallBack(func:Function):void
        {
            enterFrameFunc = func;
        }
        
        /**
         * 设置动作结束回调
         * @param func 回调函数
         */
        public function setActionOverCallBack(func:Function):void
        {
            actionOverFunc = func;
        }
        
        /**
         * 设置偏移量
         * @param x 偏移量x
         * @param y 偏移量y
         */
        public function setOffset(x:Number = 0, y:Number = 0):void
        {
            _offsetX = x;
            _offsetY = y;
        }
        
        /**
         * 设置动作
         * @param actName 动作名称
         */
        public function setAction(actName:String):void
        {
            _curAction = actName;
            if(!_clipDict) return;
            if(!_clipDict.hasOwnProperty(_curAction))
            {
                _clipDict[_curAction] = AnimationManager.getActionAnimation(sourceName,replace,_curAction,animationType,true);
                if(_clipDict[_curAction] == null)
                {
                    Logger.log("找不到动作: " + actName);
                    delete _clipDict[_curAction];
                    return;
                }
            }
            if(_curClip === _clipDict[_curAction]) return;
            if(_curClip) _curClip.removeFromParent();
            _curClip = _clipDict[_curAction];
            _curClip.GotoAndPlay(1);
            applyOffset();
            addChild(_curClip as MovieClip);
        }
        
        /**
         * 渲染动画
         */
        public function renderAnimate():void
        {
            if (!_curAction || !_curClip)
            {
                return;
            }
            if(!_isPlaying)
            {
                return;
            }
            applyOffset();
            if(enterFrameFunc) enterFrameFunc(_curAction,_curClip.currentFrame);
            _curClip.renderAnimate();
            if(_curClip.frameLeft == 0)
            {
                if(actionOverFunc) actionOverFunc(_curAction);
            }
        }
        
        public function stop():void
        {
            _isPlaying = false;
        }
        
        public function play():void
        {
            _isPlaying = true;
        }
        
        public function isPlaying():Boolean
        {
            return _isPlaying;
        }
        
        public function gotoAndPlay(frame:int):void
        {
            _isPlaying = true;
            _curClip.GotoAndPlay(frame);
        }
        
        public function gotoAndStop(frame:int):void
        {
            _isPlaying = false;
            _curClip.GotoAndStop(frame);
        }
        
        public function turnRight():void
        {
            scaleX = 1;
        }
        
        public function turnLeft():void
        {
            scaleX = -1;
        }
        
        public function getAction():String
        {
            return _curAction;
        }
        
        public function get frameLeft():int
        {
            return _curClip.frameLeft;
        }
        
        public function get currentFrame():int
        {
            return _curClip.currentFrame;
        }
        
        public function get totalFrame():int
        {
            return _curClip.totalFrame;
        }
        
        public function get totalActions():int
        {
            return UtilBase.length(_clipDict);
        }
        
        public function get loopTime():int
        {
            return _curClip.loopTime;
        }
        
        protected function applyOffset():void
        {
            if(!_curClip) return;
            _curClip.x = _offsetX;
            _curClip.y = _offsetY;
        }
        
        public function replaceClipByName(clipName:String,clip:IAnimation):void
        {
            _clipDict[clipName] = clip;
        }
        
        public function replaceClipsByName(clipNames:Array, clipVec:Vector.<IAnimation>):void
        {
            if(clipNames.length != clipVec.length) throw "NameArray Should Have the Same Length as ClipVector";
            for (var i:int = 0; i < clipNames.length; i++)
            {
                replaceClipByName(clipNames[i], clipVec[i]);
            }
        }
        
        public function getCurFrame():uint
        {
            return _curClip.currentFrame;
        }
        
        public function hide():void
        {
            visible = false;
        }
        
        public function show():void
        {
            visible = true;
        }
        
        public function getDirect():int
        {
            return scaleX;
        }
        
        public function setDirect(value:int):void
        {
            if (getDirect() != value)
            {
                _curClip.scaleX = value;
                applyOffset();
            }
        }
        
        public function changeAppearance(source:String, r:Object):void
        {
            if(UtilBase.getObjectID(r) == UtilBase.getObjectID(replace)) return;
            var curFrame:int = getCurFrame();
            sourceName = source;
            replace = r;
            _curClip.removeFromParent();
            _curClip = null;
            for (var key:String in _clipDict)
            {
                _clipDict[key] = null;
                delete _clipDict[key];
            }
            if(_curAction)
            {
                setAction(_curAction);
            }
            gotoAndPlay(curFrame);
        }
        
        /**
         * 调用此函数只是清空当前躯壳，并不会销毁动画bmd数据
         */
        public function destroy():void
        {
            for (var key:String in _clipDict)
            {
                delete _clipDict[key];
            }
            _clipDict = null;
            if(_curClip) _curClip.removeFromParent();
            _curClip = null;
            enterFrameFunc = null;
            actionOverFunc = null;
            if (parent)
            {
                parent.removeChild(this);
            }
        }
    }
}